﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;


using PlanningGIS.Util.Convertor;
using PlanningGIS.ArcGIS;
using PlanningGIS.Framework.Rule;
using PlanningGIS.Util.Log;
using PlanningGIS.Engine.Controls;
namespace PlanningGIS.DataCheck.model
{
 
    public class AttrLogicCheck : Check
    {
        public override bool Operate()
        {
            if (base.Operate() == false) return false;

            if (!(checkRule is AttrCheckRule)) return false;

            AttrCheckRule attrCheckRule = checkRule as AttrCheckRule;
            if (attrCheckRule == null) return false;

            List<object> values = new List<object>();

            if (attrCheckRule.Tag == null || attrCheckRule.Tag == "")
            {
                LogHelper.WriteLog("未请设置字段值，[" + attrCheckRule.CheckName + "]检查失败！");
                return false;
            }

            string[] strs = attrCheckRule.Tag.Split(',');
            foreach (string value in strs)
            {
                if (value.ToUpper() == "<NULL>")
                {
                    values.Add(null);
                    values.Add(DBNull.Value);
                }
                else
                    values.Add(value);
            }

            
                LogHelper.WriteLog("开始进行[" + checkRule.CheckName + "]。。。");

            int errCount = 0;

            try
            {
                errCount = Check("属性逻辑异常", pFeatLyr1, extent, "", attrCheckRule.FieldName, values);
            }
            catch (Exception ex)
            {
                
                    LogHelper.WriteLog("[" + checkRule.CheckName + "]过程出现异常，检查终止！异常信息：" + ex.Message + "\n");
                return false;
            }

            
                LogHelper.WriteLog("[" + checkRule.CheckName + "]结束。共发现" + errCount + "处错误！\n");

            return true;
        }


        public override string ToString()
        {
            return "AttrLogicCheck";
        }

        public int Check(string errType, IFeatureLayer pFeatLyr, IGeometry extent, string sql, string fieldName, List<object> values)
        {
            IFeatureClass pFeatCls = pFeatLyr.FeatureClass;

            if (values == null || values.Count == 0)
            {
               LogHelper.WriteErrLog("请先设置属性值！");
                return 0;
            }

            int idxField = pFeatCls.FindField(fieldName);
            if (idxField == -1)
            {
               LogHelper.WriteErrLog("[" + pFeatLyr.Name + "]图层未找到[" + fieldName + "]属性！");
                return 0;
            }

            IField pField = pFeatCls.Fields.get_Field(idxField);
            esriFieldType fieldType = pField.Type;

            if ((int)fieldType > 4)
            {
               LogHelper.WriteErrLog("该检查项仅支持数值型和字符串型属性的检查！");
                return 0;
            }

            IFeatureSelection pFeatSel = (IFeatureSelection)pFeatLyr;

            ISelectionSet pSelset;
            IEnumIDs pIDs;

            int errCount = 0;
            int count = 0;

            if (showFakePro != null) showFakePro(true);
            
                LogHelper.WriteLog("开始形成选择集。。。");
            pSelset = CursorHelper.GetSelset(pFeatSel, extent, sql, esriSpatialRelEnum.esriSpatialRelIntersects);
            
                LogHelper.WriteLog("形成选择集完毕。共有" + pSelset.Count + "个要素参与检查。");

            if (showFakePro != null) showFakePro(false);
            if (pSelset.Count == 0) return 0;

            if (setProcessBarMax != null) setProcessBarMax(pSelset.Count);

            pIDs = pSelset.IDs;
            long lID;

            while ((lID = pIDs.Next()) != -1)
            {
                if (IsStop()) break;

                count++;
                if (setProcessBarCurrent != null) setProcessBarCurrent(count);

                IFeature pFeature = pFeatCls.GetFeature((int)lID);

                object obj = pFeature.get_Value(idxField);
                if (obj == DBNull.Value)
                {
                    RecordListHelper.AddRecordItem(errType, pFeatLyr, null, pFeature, null, pFeature.ShapeCopy, "null");
                    continue;
                }
                if (values.Contains(obj)) continue;
                
                bool hasFound = false;

                foreach (object value in values)
                {
                    if (value == null || value == DBNull.Value) continue;
                    if (fieldType == esriFieldType.esriFieldTypeSmallInteger)
                    {
                        int temp = Int16.Parse(obj.ToString());
                        if (StringHelper.CanConvert2Int(value.ToString()))
                        {
                            if (temp == Int16.Parse(value.ToString()))
                            {
                                hasFound = true;
                                break;
                            }
                        }
                    }
                    else if (fieldType == esriFieldType.esriFieldTypeInteger)
                    {
                        int temp = Int32.Parse(obj.ToString());
                        if (StringHelper.CanConvert2Int(value.ToString()))
                        {
                            if (temp == Int32.Parse(value.ToString()))
                            {
                                hasFound = true;
                                break;
                            }
                        }
                    }
                    else if (fieldType == esriFieldType.esriFieldTypeSingle)
                    {
                        Single temp = Single.Parse(obj.ToString());
                        if (StringHelper.CanConvert2Double(value.ToString()))
                        {
                            if (temp == Single.Parse(value.ToString()))
                            {
                                hasFound = true;
                                break;
                            }
                        }
                    }
                    else if (fieldType == esriFieldType.esriFieldTypeDouble)
                    {
                        double temp = Single.Parse(obj.ToString());
                        if (StringHelper.CanConvert2Double(value.ToString()))
                        {
                            if (temp == Double.Parse(value.ToString()))
                            {
                                hasFound = true;
                                break;
                            }
                        }
                    }
                    else
                    {
                        string temp = obj.ToString();
                        if (temp == value.ToString())
                        {
                            hasFound = true;
                            break;
                        }
                    }
                }

                if (hasFound) continue;

                RecordListHelper.AddRecordItem(errType, pFeatLyr, null, pFeature, null, pFeature.ShapeCopy, obj.ToString());

                errCount++;

            }

            pFeatSel.Clear();
            if (finishPro != null) finishPro();
            return errCount;
        }
    }
}
